// main.c
// Joseph Craig, Rebecca Rush, Steven Andryzcik
// Version 6 - 12/08/2011

#include "mpx_supt.h"
#include "process.h"
#include "inter.h"
#include <dos.h>

/************Prototype***********/
void comhan();

// main
// Parameters: none
// Return: void
// Functions called: sys_init, initialize_process_queues,
// sprintf, sys_set_vect, sys_exit, initialize_io,
// printf, pcb_setup, pcb_insert, program_load,
// dispatch, empty_io
// Runs the entire program initializing the queues
// and set the sys_vector to point to syscall
// Makes Comhan a process and loads in the idle process. 
void main() {
	char buffer[BUFSIZ] = "";
	
	int
		error_code,
		failed_on = 0;
	
	ppcb np;
	context *npc;
	
	/* Initialize mpx_supt for the correct module.
	 */
	sys_init(MODULE_F);
	
	/* Attempt to initialize the process queues.  If something goes wrong, the
	 * error is unrecoverable; print an error message and quit.
	 */
	error_code = initialize_process_queues(&failed_on);
	if (error_code != OK) {
		sprintf(
			buffer,
			"\n\tFATAL ERROR: initializing queue %d caused error %d\n\n",
			failed_on,
			error_code
		);
		printf(buffer);
		sys_exit();
	}
	
	/* Attempt to set up the interrupt vector.
	 */
	if (sys_set_vec(sys_call) == ERR_SUP_INVHAN) {
		printf("Could not set interrupt vector.\n");
		sys_exit();
	}
	
	/* Attempt to initialize the I/O functionality.  If something goes wrong,
	 * the error is unrecoverable; print an error message and quit.
	 */
	error_code = initialize_io(&failed_on);
	if (error_code != OK) {
		if (failed_on == COM_PORT) {
			sprintf(
				buffer,
				"\n\tFATAL ERROR: opening the com port caused error %d\n\n",
				failed_on,
				error_code
			);
		} else if (failed_on == TERMINAL) {
			sprintf(
				buffer,
				"\n\tFATAL ERROR: opening the terminal caused error %d\n\n",
				failed_on,
				// error_code
				_doserrno
			);
		} else {
			sprintf(
				buffer,
				"\n\tFATAL ERROR: initializing queue %d caused error %d\n\n",
				failed_on,
				error_code
			);
		}
		printf(buffer);
		sys_exit();
	}
	
	//Comhan process installed in Main.
	//Highest priority.
	np = pcb_setup("COMHAN", SYSTEM, 127);
	npc = (context*) np->stack_top;
	npc->IP = FP_OFF(comhan);
	npc->CS = FP_SEG(comhan);
	npc->FLAGS = 0x200;
	npc->DS = _DS;
	npc->ES = _ES;
	//Places the process in the ready queue.
	pcb_insert(READY, np);
	
	//Load Idle as a process
	program_load(-128, "IDLE", SYSTEM);

	// Run the processes.
	dispatch();
	
	/* Attempt to clean up the I/O functionality.  If something goes wrong, the
	 * error is unrecoverable; print an error message and quit.
	 */
	error_code = empty_io(&failed_on);
	if (error_code != OK) {
		if (failed_on == COM_PORT) {
			sprintf(
				buffer,
				"\n\tFATAL ERROR: closing the com port caused error %d\n\n",
				failed_on,
				error_code
			);
		} else if (failed_on == TERMINAL) {
			sprintf(
				buffer,
				"\n\tFATAL ERROR: closing the terminal caused error %d\n\n",
				failed_on,
				error_code
			);
		} else {
			sprintf(
				buffer,
				"\n\tFATAL ERROR: freeing queue %d caused error %d\n\n",
				failed_on,
				error_code
			);
		}
		printf(buffer);
		sys_exit();
	}
	
	/* Attempt to clean up the process queues.  If something goes wrong, the
	 * error is unrecoverable; print an error message and quit.
	 */
	error_code = empty_process_queues(&failed_on);
	if (error_code != OK) {
		sprintf(
			buffer,
			"\n\tFATAL ERROR: emptying queue %d caused error %d\n\n",
			failed_on,
			error_code
		);
		printf(buffer);
		sys_exit();
	}
	
	/* The program has finished.
	 */
	printf("\n\nChewbacca thanks you for using MPX.\n\n");
	system("pause");
	sys_exit();
}